Programmable integrated circuits (ICs) may be programmed by a user to perform specified logic functions. One type of programmable IC, known as a field programmable gate array (FPGA), typically includes programmable resources that are arranged in an array of programmable tiles including, for example, input/output blocks (IOBs), configurable logic blocks (CLBs), dedicated random access memory blocks (BRAM), multipliers, digital signal processing blocks (DSPs), processors, clock managers, delay lock loops (DLLs), bus or network interfaces such as Peripheral Component Interconnect Express (PCIe) and Ethernet, and so forth.
Programmable ICs provide flexible hardware solutions that are advantageous for high performance parallel computing in advanced digital communications and video applications. For many complex applications, it may be desirable to implement a portion of the design in software (a program design) and a portion of the design in programmable resources. Many manufacturers, such as Xilinx, Inc., include embedded processor systems in a number of programmable ICs. These embedded processor systems may satisfy both the software and hardware needs of the application. Embedded processor systems often include operating memory, software instruction storage, input/output, and other components of a computer system. These systems are referred to as system-on-chip (SOC) solutions. With these systems, designers may implement a portion of the design in software and complex functions in programmable logic to increase efficiency and throughput. This architectural combination gives an advantageous mix of serial and parallel processing, flexibility, and scalability, thereby enhancing system partitioning.
Current SOC digital hardware design is done using hardware description languages (HDLs) such as Verilog and VHDL. These languages provide special constructs to handle the description of digital hardware-specific entities such as registers and clocks. While these languages are effective in describing hardware circuits, they provide little in the way of high-level abstractions to manage the complexity of modern designs. In contrast, modern software languages, and in particular object-oriented high-level languages (HLL) such as Java and C++ provide robust high-level constructs that are very effective at managing complexity and serve to improve designer productivity as well as design quality. Synthesizing compilers have been created to infer and synthesize hardware circuits from an HLL design. The ability to describe circuits using an HLL allows a designer to focus on the algorithms, rather than the implementation details.
During the process of developing a circuit design, the behavior of an implemented system is generally simulated based on a specification of the circuit design. Simulating the system helps to verify correct behavior prior to physical implementation and deployment. Wasted manufacturing costs due to faulty design may thereby be avoided.
Circuits synthesized from an HLL design may be simulated in a simulation environment alongside other circuits described in an HDL and/or along with simulation of a program to be executed on a processor of the programmable IC. In debugging an HLL design, it may be desirable to debug a hardware portion of the design while it is implemented in hardware (e.g. using programmable resources of a programmable IC). For instance, for synthesized circuits to be deployed using programmable resources of a programmable IC, it may be desirable to verify behavior of the circuit when implemented in the target hardware instead of using a model of the hardware. Furthermore, debugging in hardware may be performed at much faster speeds than simulation and debugging using a model.
It can be difficult to debug hardware from a software debugging tool. One technique to debug hardware from a software tool is to provide explicit memory-mapped access to various internal registers (e.g., control and/or status) included in the hardware by bringing signals to a module's interface. Using this technique, changes to a set of variables that are to be monitored in an HLL function require calls to the function to be changed as well (either in the software test bench or in an accompanying hardware test bench). Configuration of an interface to provide memory-mapped access to internal registers of hardware generated through HLL synthesis tools requires knowledge about hardware design techniques. Moreover, such configuration is a lengthy manual process, which may present a substantial barrier for a software designer.